Spring3 MVC使用@ResponseBody后会产生很大的响应头(Accept-Charset会达到4K+),原因在于默认情况下StringHttpMessageConverter.writeInternal()会将所有可用字符集回写到response响应头中:问题来了
解决方式:
一般我们都会重写springs mvc的HttpMessageConverter,改为utf-8编码:
- package com.goldpalm.core.spring.mvc;
-
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.UnsupportedEncodingException;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.List;
-
- import org.springframework.http.HttpInputMessage;
- import org.springframework.http.HttpOutputMessage;
- import org.springframework.http.MediaType;
- import org.springframework.http.converter.AbstractHttpMessageConverter;
- import org.springframework.util.FileCopyUtils;
-
- /**
- * 重写SpringMVC的字符串转换器,使用UTF-8编码
- * @since 2012-7-5 下午2:28:19
- * @author Jesse Lu
- */
- public class UTF8StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
-
- public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
-
- private final List<Charset> availableCharsets;
-
- private boolean writeAcceptCharset = true;
-
- public UTF8StringHttpMessageConverter() {
- super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL);
- this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
- }
-
- /**
- * Indicates whether the {@code Accept-Charset} should be written to any outgoing request.
- * <p>
- * Default is {@code true}.
- */
- public void setWriteAcceptCharset(boolean writeAcceptCharset) {
- this.writeAcceptCharset = writeAcceptCharset;
- }
-
- @Override
- public boolean supports(Class<?> clazz) {
- return String.class.equals(clazz);
- }
-
- @SuppressWarnings("rawtypes")
- @Override
- protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
- Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
- return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
- }
-
- @Override
- protected Long getContentLength(String s, MediaType contentType) {
- Charset charset = getContentTypeCharset(contentType);
- try {
- return (long) s.getBytes(charset.name()).length;
- } catch (UnsupportedEncodingException ex) {
- // should not occur
- throw new InternalError(ex.getMessage());
- }
- }
-
- @Override
- protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {
- if (writeAcceptCharset) {
- outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
- }
- Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
- FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));
- }
-
- /**
- * Return the list of supported {@link Charset}.
- * <p>
- * By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
- * @return the list of accepted charsets
- */
- protected List<Charset> getAcceptedCharsets() {
- return this.availableCharsets;
- }
-
- private Charset getContentTypeCharset(MediaType contentType) {
- if (contentType != null && contentType.getCharSet() != null) {
- return contentType.getCharSet();
- } else {
- return DEFAULT_CHARSET;
- }
- }
-
- }
在xm中配置:注意红色圈起来的配置

- <mvc:annotation-driven>
- <mvc:message-converters>
- <bean class="com.goldpalm.core.spring.mvc.UTF8StringHttpMessageConverter">
- <property name="writeAcceptCharset" value="false" />
- </bean>
- </mvc:message-converters>
- </mvc:annotation-driven>